import java.util.*;
import java.io.*;
import javax.swing.*;

public class model{
	   
	   int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5; 
		     
	   Enemy1 enemy1; //enemy classes
       Enemy2 enemy2;
       Enemy3 enemy3;
       Enemy4 enemy4;
       Thread e1,e2,e3,e4; //each enemy runs in its own thread
       Avoider avoid;
       controller control;
       Random generator; //random number Gen for new objects
       
       String score; //variable to keep score
       Hashtable<Integer, String> highscore; //hashtable to store scores

       String hs, name, temp; //variablles for reading score
       String finalScore, inputName;
       
	public model(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int x5, int y5, Avoider avoid, controller control){
	   
	   this.x1 = x1;
	   this.y1 = y1;
	   this.x2 = x2;
	   this.y2 = y2;
	   this.x3 = x3;
	   this.y3 = y3;
	   this.x4 = x4;
	   this.y4 = y4;
	   this.x5 = x5;
	   this.y5 = y5; 
	   this.avoid = avoid;
	   this.control = control;
	   
	   generator = new Random();
	   
	     highscore = new Hashtable<Integer, String>();
         BuildHighScores();
       
         Enemy1 enemy1 = new Enemy1();
         e1 = new Thread(enemy1);
         e1.start();
        
         Enemy2 enemy2 = new Enemy2();
         e2 = new Thread(enemy2);
         e2.start();
      
         Enemy3 enemy3 = new Enemy3();
         e3 = new Thread(enemy3);
         e3.start();

         Enemy4 enemy4 = new Enemy4();
         e4 = new Thread(enemy4);
         e4.start();
		}
 class Enemy1 implements Runnable{
	   //each enemey runs in its own thread
       public void run(){
		  while(true){
			if(avoid.getRun()){
		   //move object randomly
		   x2 = x2+generator.nextInt(7);
		   y2 = y2+generator.nextInt(7);
		   if(x2>500 || y2>500){
			   int side = generator.nextInt(2);
			   //which side should the ball appear on
			   if(side==0)
			   {x2=0;
			    y2=generator.nextInt(470);}
			   if(side==1)
			   {x2=generator.nextInt(470);
			    y2=0;}}
             x1 = avoid.getx1();
             y1 = avoid.gety1();
		    if ((x1+ 30>x2 && x1-30<x2)&&(y1+ 30>y2 && y1-30<y2))
              { //calculate intersection for game over
				GameOver();
               } //draw the moved object
             avoid.set2(x2,y2);
		   avoid.drawSurface.repaint();}
		   try{
		//wait 10 milliseconds
		   Thread.sleep(10);}
		   catch(InterruptedException e) {
			  System.out.println("Interrupt Caught");
      }}}}

    class Enemy2 implements Runnable{

       public void run(){
		  while(true){
			  if(avoid.getRun()){
		   //move object randomly (each object has different pattern)
		   if(generator.nextInt(2)==1)
		   x3 = x3+generator.nextInt(7);
		   else
		   x3 = x3-generator.nextInt(7);
		   y3 = y3-generator.nextInt(12);
		   if(y3 < -30){
			    x3=generator.nextInt(470);
			    y3=500;}
		   x1 = avoid.getx1();
           y1 = avoid.gety1();
		if ((x1+ 30>x3 && x1-30<x3)&&(y1+ 30>y3 && y1-30<y3))
              {
				GameOver();
               }
           avoid.set3(x3,y3);
		   avoid.drawSurface.repaint();}
		   try{
		//wait 10 milliseconds
		   Thread.sleep(10);}
		   catch(InterruptedException e) {
			   System.out.println("Interrupt Caught");
      }}}}

    class Enemy3 implements Runnable{

       public void run(){
		  while(true){
			  if(avoid.getRun()){
		   //move object randomly
		   x4 = x4-generator.nextInt(7);
		   y4 = y4+generator.nextInt(7);
		   if(x4<-30 || y4>500){
			   int side = generator.nextInt(2);
			   //which side should the ball appear on
			   if(side==0)
			   {x4=500;
			    y4=generator.nextInt(470);}
			   if(side==1)
			   {x4=generator.nextInt(470);
			    y4=500;}}
			 x1 = avoid.getx1();
             y1 = avoid.gety1();
          if ((x1+ 30>x4 && x1-30<x4)&&(y1+ 30>y4 && y1-30<y4))
              {
				GameOver();
               }
               avoid.set4(x4,y4);
		   avoid.drawSurface.repaint();}
		   try{
		//wait 10 milliseconds
		   Thread.sleep(10);}
		   catch(InterruptedException e) {
			System.out.println("Interrupt Caught");
      }}}}

  class Enemy4 implements Runnable{
       int count=0;
       public void run(){
		  while(true){
			  if(avoid.getRun()){
		   //move object randomly
		   x5 = x5-generator.nextInt(7);
		   if(count<30){
		   y5 = y5+generator.nextInt(7);
		   count++;
		   if(count==30)count=60;
		   }
		   else{
		   y5 = y5-generator.nextInt(7);
		   count--;
		   if(count==29)count=0;}
		   if(x5<-30 || y5>500  || y5<-30){
			   //which side should the ball appear on
			    x5=500;
			    y5=generator.nextInt(470);}
			 x1 = avoid.getx1();
             y1 = avoid.gety1();
          if ((x1+ 30>x5 && x1-30<x5)&&(y1+ 30>y5 && y1-30<y5))
              {
				GameOver();
               }
            avoid.set5(x5,y5);
		   avoid.drawSurface.repaint();}
		   try{
		//wait 10 milliseconds
		   Thread.sleep(10);}
		   catch(InterruptedException e) {
			System.out.println("Interrupt Caught");
      }}}}
      
       public void GameOver()  //ends game
 {
        avoid.setNewGame(false);
        avoid.setRun(false);
        avoid.setFreeze(true);
        avoid.setStop(false);
        score = avoid.getTime();
        try{Thread.currentThread().sleep(20);}
        catch(InterruptedException e){}
        avoid.drawSurface.repaint();
        if(Long.parseLong(score)>Long.parseLong(avoid.getLowestScore()))
        {
            inputName  =  JOptionPane.showInputDialog
                    (null, "                        Congratulations!\n" +
                    "You've made the High Scores with the time of " + avoid.getTimeMs() +
                    ".\n                  Please enter your name below: ","GAME OVER", JOptionPane.PLAIN_MESSAGE );
            if((inputName != null) && (inputName.length() > 0)){
            if(inputName.length()>15)
            inputName=inputName.substring(0,15);} //only 15 characters
            else inputName = "Anonymous";
            remakeHighScores(inputName);
            saveHighScores();
            avoid.setFreeze(false);
        }
        else
        {
            while(avoid.getFreeze())
            {
                try{Thread.currentThread().sleep(20);}
                catch(InterruptedException e){}
            }
        }

            // resets game variables to initals
       avoid.set1(220,220);
       avoid.set2(-30,-30);
       avoid.set3(220,500);
       avoid.set4(500,0);
       avoid.set5(500,280);
       avoid.setNewGame(true); //show  new game screen

        control.origCursor(); //show cursor
        avoid.drawSurface.repaint();
        return;
 }

 public  void BuildHighScores()
      {  //Build The high scores from file

         try {
            File f = new File("highScores.dat");
            if(!f.exists()){
					f.createNewFile();
					highscore.put(1,"10000;A"); 
					highscore.put(2,"9000;V"); 
					highscore.put(3,"8000;O"); 
					highscore.put(4,"7000;I"); 
					highscore.put(5,"6000;D"); 
					highscore.put(6,"5000;E"); 
					highscore.put(7,"4000;R"); 
					highscore.put(8,"3000;*"); 
					highscore.put(9,"2000;*"); 
					highscore.put(10,"1000;*"); 
					saveHighScores();
			}
			else{
            Scanner scan = new Scanner(f);
            String line;
            int i = 0;
           while(scan.hasNext())
            {
               line = scan.nextLine();//reads in a line from the file
               i++;
               highscore.put(new Integer(i),line); // adds line to hash table
           } // close outer while
           } 
         } // close try
            catch(FileNotFoundException e)
            {
               System.out.println("File Not Found: ") ; // !!FILE_NOT_FOUND
            }
            catch(IOException e)
            {
               System.out.println("IOException " + e.getMessage() ); // !!READ_ONLY!!
            }
      }// close BuildHighScores
      
      
 public void remakeHighScores(String inputtedName)
 { //remakes HashTable
     int i = 1;
     while(i<11)
     {
         hs = highscore.get(i); // gets current line of highscores
         Scanner scan = new Scanner(hs);
         scan.useDelimiter(";");
         String thisScore = scan.next();
         if(Long.parseLong(score)>Long.parseLong(thisScore))
         {
             int j = 10;
             while(j>i)  // works from bottom moving lower score down
             {
                 hs = highscore.get(j-1);  // takes one above
                 highscore.put(new Integer(j),hs); // puts it one below
                 j--;
             }
                 if (j==i) // adds your score at the corect place
                    highscore.put(new Integer(i),score+";"+inputtedName);             
                 i = 11; // breaks out of loop
         }

         i++;
     }
 }

 public void saveHighScores()
 {
     try { //saves high scores to a file
        BufferedWriter out = new BufferedWriter(new FileWriter("highScores.dat"));
        for(int i = 1;i<11;i++)
        {
            hs = highscore.get(i);
            out.write(hs);
            out.newLine();
        }

        out.close();
    } catch (IOException e) {System.out.println("Error writing file!");}
 }
 
 public String getHighscore(int i)
 {
	 return highscore.get(i);
 }
      
      }
